"""
@文件: admin.py
@Author: ZJJ
@Email: 1065377805@qq.com
@Time: 2025/3/7
@Des:管理员文件
"""
import logging
from datetime import timedelta
from os import access
from typing import List

import jwt
from fastapi import APIRouter, Query
from fastapi.params import Security
from fastapi.requests import Request
from tortoise.expressions import F

from api.admin.common import write_access_log
from config import settings
from core.Auth import check_permission, creat_token
from core.Response import fail, success, res_ajax
from core.Utils import en_password, verify_password
from model.base import Admin, Role, Access
from schemas import admin

router = APIRouter(prefix="/admin", tags=["admin"])

# 添加管理员
@router.post("/add",
             summary="管理员添加",
             # dependencies=[Security(check_permission,scopes=["admin_add"])]
             )
async def admin_add(post: admin.CreateAdmin):
    """
    创建用户
    :param post:
    :return:
    """
    # 过滤用户
    get_admin = await Admin.get_or_none(username=post.username)
    print(get_admin)
    if get_admin:
        return fail(msg="用户名已经存在!")
    # 密码进行加密处理
    post.password = en_password(post.password)

    # 创建用户
    create_admin = await Admin.create(**post.dict())
    if not create_admin:
        return fail(msg="用户创建失败!")
    if post.roles:
        roles = await Role.filter(id__in=post.roles,role_status=True)
        await create_admin.role.add(*roles)
    return success(msg="用户创建成功")

# 管理员删除
@router.delete("/delete",
               summary="管理员删除",
               dependencies=[Security(check_permission,scopes=["admin_delete"])]
               )
async def admin_delete(req:Request,user_id: int):
    """
    删除用户
    """
    if req.state.user_id == user_id:
        return fail(msg="不能删除自己!")
    delete_action = await Admin.filter(pk=user_id).delete()
    if not delete_action:
        return fail(msg=f"用户{user_id}不存在!")
    return success(msg=f"删除成功")

# 管理员信息修改
@router.put("/update",
            summary="管理员信息修改",
            dependencies=[Security(check_permission,scopes=["admin_update"])]
            )
async def admin_update(post: admin.UpdateAdmin):
    """
    修改用户信息
    :param post:
    :return:
    """
    # 检查用户存不存在
    admin_check = await Admin.get_or_none(pk = post.user_id)
    if not admin_check or admin_check.pk == 1:
        return fail(msg="用户不存在")
    if admin_check.username != post.username:
        check_username = await Admin.get_or_none(username=post.username)
        if check_username:
            return fail(msg=f"用户名{check_username}已经存在")

    # 判断是否需要更新密码
    if admin_check.password:
        post.password = en_password(post.password)

    data = post.model_dump()
    if not post.password:
        data.pop("password")
    data.pop("id")
    await Admin.filter(pk=post.id).update(**data)
    return success(msg="更新成功!")

# 获取当前登录用户信息
@router.get("/info",summary="获取当前用户信息",
            response_model=admin.CurrentAdmin,
            dependencies=[Security(check_permission,scopes=["admin_info"])])
async def admin_info(req:Request):
    user_data = await Admin.get_or_none(pk=req.state.user_id)
    if not user_data:
        return fail(msg=f"用户ID{req.state.user_id}不存在")
    # 非超级管理员
    access=[]
    if not req.state.user_type:
        # 二级菜单权限
        two_level_access = await Access.filter(role__user__id=req.state.user_id, is_check=True).values_list("parent_id")
        two_level_access = [i[0] for i in two_level_access]
        # 一级权限
        one_level_access = await Access.filter(id__in = list(set(two_level_access))).values_list("parent_id")
        query_access = await Access.filter(id__in=list(set(one_level_access + two_level_access))).values_list("scopes")
        access = [i[0] for i in query_access]

    # 处理手机号 ****
    if user_data.user_phone:
        user_data.user_phone = user_data.user_phone.replace(user_data.user_phone[3:7], "****")
    # 将作用域加入到用户信息中
    user_data.__setattr__("scopes", access)
    return success(msg="用户信息", data=user_data.__dict__)

# 用户个人信息修改
@router.put('/info',
            summary="个人信息修改",
            dependencies=[Security(check_permission,scopes=["update_user_info"])]
            )
async def update_user_info(req:Request,post: admin.UpdateAdminInfo):
    """
    修改个人信息
    :param req:
    :param post:
    :return:
    """
    # 说明
    # 这个位置原本写法  await User.filter(id=req.state.user_id).update(**post.dict(exclude_none=True))
    # .dict方法在旧版的 .dict() 方法被标记为弃用，推荐使用 .model_dump()
    await Admin.filter(id = req.state.user_id).update(**post.model_dump(exclude_none=True))
    return success(msg="更新成功!")

# 获取用户列表
@router.get('/list',summary="用户列表",
            response_model=admin.UserListData,
            dependencies=[Security(check_permission,scopes=["admin_list"])]
            )
async def admin_list(
        pageSize: int = 10,
        current: int = 1,
        username: str = Query(None),
        user_phone: str = Query(None),
        user_status: bool = Query(None),
        create_time: List[str] = Query(None)
                     ):
    """
    获取所有管理员列表
    :param pageSize:
    :param current:
    :param username:
    :param user_phone:
    :param user_status:
    :param create_time:
    :return:
    """
    query = {}
    if username:
        query.setdefault("username", username)
    if user_phone:
        query.setdefault("user_phone", user_phone)
    if user_status is not None:
        query.setdefault("user_status", user_status)
    if create_time:
        query.setdefault("create_time__range", create_time)
    user_data = Admin.annotate(key=F("id")).filter(**query).filter(id__not=1).all()
    total = await user_data.count()
    data = await user_data.limit(pageSize).offset(pageSize * (current - 1)).order_by("-create_time").values("key", "id", "username", "user_type", "user_phone", "user_email",
        "user_status", "header_img", "sex", "remarks", "create_time","nickname", "full_name","update_time")
    return res_ajax(code=True,data=data,total=total)


# 管理员登录
# @router.post("/login",response_model=admin.AdminLogin,summary+="管理员登陆") //这里添加了响应数据验证，但是一致报错，数据验证模型一直报错暂时去掉了，还需要研究一下
@router.post("/login",summary="管理员登陆")
async def admin_login(req:Request,post: admin.AccountLogin):
    """
    管理员登陆
    :param req:
    :param post:
    :return:1213
    """
    # 手机号登录 暂未开通
    # 账号密码登录
    if post.username and post.password:
        get_user = await Admin.get_or_none(username=post.username)
        if not get_user:
            return fail(msg=f"用户{post.username}登陆失败")
        if not get_user.password:
            return fail(msg=f"用户{post.username}密码验证失败")
        if not verify_password(post.password,get_user.password):
            print(post.password)
            return fail(msg="密码验证失败!")
        if not get_user.user_status:
            return fail(msg=f"该用户已被禁用")
        jwt_data = {
            "user_id":get_user.pk,
            "user_type":get_user.user_type,
        }
        access_token = creat_token(data=jwt_data)
        refresh_token = creat_token(data=jwt_data, expires_delta=timedelta(days=7))  # refreshToken 有效期为7天
         # 将 refreshToken 存储到 Redis
        await req.app.state.redis.set(f"refresh_token:{get_user.pk}", refresh_token, ex=7 * 24 * 60 * 60)
        data = {
            "access_token": access_token,
            "refresh_token": refresh_token,
            "expires_in": settings.JWT_ACCESS_TOKEN_EXPIRE_MINUTES * 60
        }
        await write_access_log(req, get_user.pk, "通过用户名登陆了系统!")
        return success(msg="登陆成功😄", data=data)
    return fail(msg="至少选择一种登陆方式!")

# ... existing code ...

@router.post("/refresh-token", summary="刷新 accessToken")
async def refresh_token(req: Request, refresh_token: str):
    """
    刷新 accessToken
    :param req:
    :param refresh_token:
    :return:
    """
    try:
        payload = jwt.decode(
            refresh_token,
            settings.JWT_SECRET_KEY,
            algorithms=[settings.JWT_ALGORITHM]
        )
        user_id = payload.get("user_id")
        user_type = payload.get("user_type")
        if not user_id or not user_type:
            return fail(msg="无效的 refreshToken")

        # 验证 refreshToken 是否有效
        stored_refresh_token = await req.app.state.redis.get(f"refresh_token:{user_id}")
        if stored_refresh_token != refresh_token:
            return fail(msg="无效的 refreshToken")

        # 生成新的 accessToken
        jwt_data = {
            "user_id": user_id,
            "user_type": user_type,
        }
        new_access_token = creat_token(data=jwt_data)
        return success(msg="刷新成功", data={"access_token": new_access_token})
    except jwt.exceptions.ExpiredSignatureError:
        return fail(msg="refreshToken 已过期")
    except jwt.exceptions.InvalidTokenError:
        return fail(msg="无效的 refreshToken")